#ifndef MAIN_H_
#define MAIN_H_

#include <time.h>
#include <sys/resource.h>
#include <netinet/in.h>

#define OPEN_MAX_DEF        2048
#define BUF_SIZE_MIN        1024
#define BUF_SIZE_MAX        (BUF_SIZE_MIN * 1024)
#define BUF_SIZE_DEF        (BUF_SIZE_MIN * 4)

#define DEF_CFG_FILE        "/etc/shadowsocks.json"
#define DEF_PID_FILE        "/var/run/%s.pid"
#define DEF_SRV_PORT        "8338"
#define DEF_BIND_ADDR       "::"
#define DEF_LISTEN_PORT     "1080"
#define DEF_CRYPTO          "aes-256-cfb"
#define DEF_ACCEPT_TIMEOUT  5
#define DEF_SOCKET_TIMEOUT  300
#define DEF_CONNECT_TIMEOUT 30
#define DEF_CACHE_EXPIRE    3600

#define DEF_SERVER_WEIGHT   5
#define SERVER_WEIGHT_MAX   1000

/* for udns */
#define HAVE_IPv6 1

struct server_info {
    const char *addr;
    const char *passwd;
    const char *crypt_method;
    int weight;
    in_port_t port;
    uint16_t flags; /* internal use */
};

struct cfg {
    const char *prog_name;
    const char *config_file;
    struct {
        struct server_info *server_infos;
        int server_cnt;
        int server_available_idx;
        int server_initial_weight;
    };
    const char *local_bind;
    const char *local_listen;
    int socket_timeout;
    int connect_timeout;
    int accept_timeout; // the timeout of new connection after accept(2)
    int daemon;
    const char *pidfile;
    time_t dns_cache_expire;
    unsigned rand_seed;

    size_t buf_size;
    unsigned long long open_max;
};

void config(struct cfg *cfg, int argc, char *argv[]);

#endif /* MAIN_H_ */
